#include "mapinfowrite.h"


MapInfoWrite::MapInfoWrite()
{
}

//重置mapinfo所有节点信息
void MapInfoWrite::resetMapInfo()
{
    addMapInfo();
}

//把mapInfo中的所有信息添加到全局XML(GlobalRwXml)中，添加前会先删除原有的MapInfo所有相关节点
void MapInfoWrite::addMapInfo()
{
    resetHeader();
    resetRoad();
    resetController();
    resetJunction();
}

//删除所有地图信息
void MapInfoWrite::delMapInfo()
{
    delHeader();
    delRoad();
    delController();
    delJunction();
}

//重置header节点
void MapInfoWrite::resetHeader()
{
    delHeader();

    addHeader(__MAPDATA->getHeader());
}

//添加header节点，为保证只有一个header，如果已有的header会先删掉
void MapInfoWrite::addHeader(const Header &header)
{
    delHeader();//保证只有一个header节点

    TiXmlElement *pRoot = GlobalRwXml::getRwxml()->getDoc()->RootElement();
//    if(nullptr == pRoot)
//    {
//        pRoot = new TiXmlElement(XML_ROOT); //root节点不存在则新建
//        GlobalRwXml::getRwxml()->getDoc()->LinkEndChild(pRoot);
//    }

    TiXmlElement *pHeader = new TiXmlElement(XML_HEADER);
    pRoot->LinkEndChild(pHeader);

    //设置header属性
    pHeader->SetAttribute(XML_DATE, header.date.c_str());
    pHeader->SetAttribute(XML_NAME, header.name.c_str());
    pHeader->SetAttribute(XML_REVMAJOR, header.revMajor.c_str());
    pHeader->SetAttribute(XML_REVMINOR, header.revMinor.c_str());
    pHeader->SetDoubleAttribute(XML_EAST, header.east);
    pHeader->SetDoubleAttribute(XML_SOUTH, header.south);
    pHeader->SetDoubleAttribute(XML_WEST, header.west);
    pHeader->SetDoubleAttribute(XML_NORTH, header.north);
    pHeader->SetAttribute(XML_VENDOR, header.vendor.c_str());
    pHeader->SetAttribute(XML_VERSION, header.version.c_str());

    if(!header.geoReference.empty())
    {
        TiXmlElement *pGeo = new TiXmlElement(XML_GEO);
        pHeader->LinkEndChild(pGeo);

        pGeo->SetValue(header.geoReference.c_str());
    }
}

//删除header节点
void MapInfoWrite::delHeader()
{
    auto opxml = GlobalRwXml::getRwxml();
    TiXmlNode *pHeaderNode = opxml->getDoc()->RootElement()->FirstChild(XML_HEADER);
    if(nullptr != pHeaderNode)
    {
        opxml->delSingleNode(pHeaderNode);
    }
}

//先清空所有road节点，然后把MapInfo中的road信息重新添加进去
void MapInfoWrite::resetRoad()
{
    delRoad();

    const QVector<SRoad> &qvecRoad = __MAPDATA->getRoad();
    for(auto itRoad = qvecRoad.begin(); itRoad != qvecRoad.end(); itRoad++)
    {
        addRoad(*itRoad);
    }
}

//添加一个road节点
void MapInfoWrite::addRoad(const SRoad &road)
{
    TiXmlElement *pRoot = GlobalRwXml::getRwxml()->getDoc()->RootElement();

    TiXmlElement *pRoad = getRoadElement(road);
    pRoot->LinkEndChild(pRoad);
}

//删除全部road节点
void MapInfoWrite::delRoad()
{
    auto opxml = GlobalRwXml::getRwxml();
    TiXmlNode *pRoadNode = opxml->getDoc()->RootElement()->FirstChild(XML_ROAD);
    TiXmlNode *pRoadNodeNext = pRoadNode->NextSibling();
    while (nullptr != pRoadNode)
    {
        opxml->delSingleNode(pRoadNode);
        pRoadNode = pRoadNodeNext;
        pRoadNodeNext = pRoadNode->NextSibling();
    }
}

void MapInfoWrite::delRoad(const SRoad &road)
{
    delRoad(road.id);
}

void MapInfoWrite::delRoad(const std::string &roadId)
{
    auto opxml = GlobalRwXml::getRwxml();
    TiXmlNode *pRoadNode = opxml->selectSingleNode(XML_ROAD, XML_ID, roadId);
    opxml->delSingleNode(pRoadNode);
}

void MapInfoWrite::updateRoad(const SRoad &road)
{
    auto opxml = GlobalRwXml::getRwxml();
    TiXmlNode *pRoadNode = opxml->selectSingleNode(XML_ROAD, XML_ID, road.id);
    opxml->getDoc()->RootElement()->InsertAfterChild(pRoadNode, *getRoadElement(road));
    opxml->delSingleNode(pRoadNode);
}

void MapInfoWrite::addRoadLink(TiXmlElement *pRoad, const RoadLink roadLink)
{
    delRoadLink(pRoad);//保证一个road节点下只有一个link节点

    TiXmlElement *pRoadLink = new TiXmlElement(XML_LINK);
    TiXmlElement *pRoadLinkPreNode = new TiXmlElement(XML_PREDECESSOR);
    TiXmlElement *pRoadLinkSucNode = new TiXmlElement(XML_SUCCESSOR);

    pRoad->LinkEndChild(pRoadLink);
    pRoadLink->LinkEndChild(pRoadLinkPreNode);
    pRoadLink->LinkEndChild(pRoadLinkSucNode);

    pRoadLinkPreNode->SetAttribute(XML_ELEMENTID, roadLink.predecessor.elementId.c_str());
    pRoadLinkPreNode->SetAttribute(XML_ELEMENTTYPE, roadLink.predecessor.elementType.c_str());
    pRoadLinkPreNode->SetAttribute(XML_CONTACTPOINT, roadLink.predecessor.contactPoint.c_str());

    pRoadLinkSucNode->SetAttribute(XML_ELEMENTID, roadLink.successor.elementId.c_str());
    pRoadLinkSucNode->SetAttribute(XML_ELEMENTTYPE, roadLink.successor.elementType.c_str());
    pRoadLinkSucNode->SetAttribute(XML_CONTACTPOINT, roadLink.successor.contactPoint.c_str());
}

void MapInfoWrite::delRoadLink(TiXmlElement *pRoad)
{
    TiXmlNode *pRoadLink = pRoad->FirstChild(XML_LINK);
    if(nullptr != pRoadLink)
    {
        pRoad->RemoveChild(pRoadLink);
    }
}

void MapInfoWrite::addRoadType(TiXmlElement *pRoad, const RoadType roadType)
{
    delRoadType(pRoad);//保证一个road节点下只有一个type节点

    TiXmlElement *pRoadType = new TiXmlElement(XML_TYPE);
    pRoad->LinkEndChild(pRoadType);

    pRoadType->SetAttribute(XML_S, roadType.s.c_str());
    pRoadType->SetAttribute(XML_TYPE, roadType.type.c_str());
}

void MapInfoWrite::delRoadType(TiXmlElement *pRoad)
{
    TiXmlNode *pRoadType = pRoad->FirstChild(XML_TYPE);
    if(nullptr != pRoadType)
    {
        pRoad->RemoveChild(pRoadType);
    }
}

void MapInfoWrite::addPlanView(TiXmlElement *pRoad, const PlanView planView)
{
    delPlanView(pRoad);//保证一个road节点下只有一个planView节点

    TiXmlElement *pPlanView = new TiXmlElement(XML_PLANVIEW);
    pRoad->LinkEndChild(pPlanView);

    for(auto itGeometry = planView.qvecGeometry.begin(); itGeometry != planView.qvecGeometry.end(); itGeometry++)
    {
        TiXmlElement *pGeometry = new TiXmlElement(XML_GEOMETRY);
        TiXmlElement *pGeometryType = new TiXmlElement(itGeometry->type.c_str());

        pPlanView->LinkEndChild(pGeometry);
        pGeometry->LinkEndChild(pGeometryType);

        pGeometry->SetDoubleAttribute(XML_HDG, itGeometry->hdg);
        pGeometry->SetDoubleAttribute(XML_LENGTH, itGeometry->length);
        pGeometry->SetDoubleAttribute(XML_S, itGeometry->s);
        pGeometry->SetDoubleAttribute(XML_X, itGeometry->x);
        pGeometry->SetDoubleAttribute(XML_Y, itGeometry->y);

        if(XML_ARC == itGeometry->type)
        {
            pGeometryType->SetDoubleAttribute(XML_CURVATURE, itGeometry->extend.a);
        }
        else if(XML_SPIRAL == itGeometry->type)
        {
            pGeometryType->SetDoubleAttribute(XML_CURVSTART, itGeometry->extend.a);
            pGeometryType->SetDoubleAttribute(XML_CURVEND, itGeometry->extend.b);
        }
        else if(XML_POLY3 == itGeometry->type)
        {
            pGeometryType->SetDoubleAttribute(XML_A, itGeometry->extend.a);
            pGeometryType->SetDoubleAttribute(XML_B, itGeometry->extend.b);
            pGeometryType->SetDoubleAttribute(XML_C, itGeometry->extend.c);
            pGeometryType->SetDoubleAttribute(XML_D, itGeometry->extend.d);
        }
    }
}

void MapInfoWrite::delPlanView(TiXmlElement *pRoad)
{
    TiXmlNode *pPlanView = pRoad->FirstChild(XML_PLANVIEW);
    if(nullptr != pPlanView)
    {
        pRoad->RemoveChild(pPlanView);
    }
}

void MapInfoWrite::addElevationProfile(TiXmlElement *pRoad, const ElevationProfile elevationProfile)
{
    delElevationProfile(pRoad);//保证一个road节点下只有一个elevationProfile节点

    TiXmlElement *pElevationProfile = new TiXmlElement(XML_ELEVATIONPROFILE);
    pRoad->LinkEndChild(pElevationProfile);

    for(auto itElevation = elevationProfile.qvecElevation.begin(); itElevation != elevationProfile.qvecElevation.end(); itElevation++)
    {
        TiXmlElement *pElevation = new TiXmlElement(XML_ELEVATION);
        pElevationProfile->LinkEndChild(pElevation);

        pElevation->SetDoubleAttribute(XML_S, itElevation->s);
        pElevation->SetDoubleAttribute(XML_A, itElevation->coefficients.a);
        pElevation->SetDoubleAttribute(XML_B, itElevation->coefficients.b);
        pElevation->SetDoubleAttribute(XML_C, itElevation->coefficients.c);
        pElevation->SetDoubleAttribute(XML_D, itElevation->coefficients.d);
    }
}

void MapInfoWrite::delElevationProfile(TiXmlElement *pRoad)
{
    TiXmlNode *pElevationProfile = pRoad->FirstChild(XML_ELEVATIONPROFILE);
    if(nullptr != pElevationProfile)
    {
        pRoad->RemoveChild(pElevationProfile);
    }
}

void MapInfoWrite::addRoadLanes(TiXmlElement *pRoad, const Lanes lanes)
{
    delElevationProfile(pRoad);//保证一个road节点下只有一个lanes节点

    TiXmlElement *pRoadLanes = new TiXmlElement(XML_LANES);
    pRoad->LinkEndChild(pRoadLanes);

    for(auto itLaneOffset = lanes.qvecLaneOffset.begin(); itLaneOffset != lanes.qvecLaneOffset.end(); itLaneOffset++)
    {
        TiXmlElement *pLaneOffset = new TiXmlElement(XML_LANEOFFSET);
        pRoadLanes->LinkEndChild(pLaneOffset);

        pLaneOffset->SetDoubleAttribute(XML_S, itLaneOffset->s);
        pLaneOffset->SetDoubleAttribute(XML_A, itLaneOffset->coefficients.a);
        pLaneOffset->SetDoubleAttribute(XML_B, itLaneOffset->coefficients.b);
        pLaneOffset->SetDoubleAttribute(XML_C, itLaneOffset->coefficients.c);
        pLaneOffset->SetDoubleAttribute(XML_D, itLaneOffset->coefficients.d);
    }

    for(auto itLaneSection = lanes.qvecLaneSection.begin(); itLaneSection != lanes.qvecLaneSection.end(); itLaneSection++)
    {
        TiXmlElement *pLaneSection = new TiXmlElement(XML_LANESECTION);
        pRoadLanes->LinkEndChild(pLaneSection);

        pLaneSection->SetDoubleAttribute(XML_S, itLaneSection->s);

        if(itLaneSection->left.bExist)
        {
            TiXmlElement *pLaneSectionLayout = new TiXmlElement(XML_LEFT);
            addLaneSectionChild(pLaneSectionLayout, itLaneSection->left);
        }

        if(itLaneSection->center.bExist)
        {
            TiXmlElement *pLaneSectionLayout = new TiXmlElement(XML_CENTER);
            addLaneSectionChild(pLaneSectionLayout, itLaneSection->center);
        }

        if(itLaneSection->right.bExist)
        {
            TiXmlElement *pLaneSectionLayout = new TiXmlElement(XML_RIGHT);
            addLaneSectionChild(pLaneSectionLayout, itLaneSection->right);
        }
    }
}

void MapInfoWrite::delRoadLanes(TiXmlElement *pRoad)
{
    TiXmlNode *pRoadLanes = pRoad->FirstChild(XML_LANES);
    if(nullptr != pRoadLanes)
    {
        pRoad->RemoveChild(pRoadLanes);
    }
}

void MapInfoWrite::addLaneSectionChild(TiXmlElement *pLaneSectionLayout, const Layout layout)
{
    for(auto itLane = layout.qvecLane.begin(); itLane != layout.qvecLane.end(); itLane++)
    {
        TiXmlElement *pLane = new TiXmlElement(XML_LANE);
        pLaneSectionLayout->LinkEndChild(pLane);

        pLane->SetAttribute(XML_ID, itLane->id.c_str());
        pLane->SetAttribute(XML_LEVEL, itLane->level.c_str());
        pLane->SetAttribute(XML_TYPE, itLane->type.c_str());

        if(itLane->link.bExist)
        {
            TiXmlElement *pLaneLink = new TiXmlElement(XML_LINK);
            pLane->LinkEndChild(pLaneLink);

            if(itLane->link.predecessor.bExist)
            {
                TiXmlElement *pLaneLinkPre = new TiXmlElement(XML_PREDECESSOR);
                pLaneLink->LinkEndChild(pLaneLinkPre);

                pLaneLinkPre->SetAttribute(XML_ID, itLane->link.predecessor.id.c_str());
            }

            if(itLane->link.successor.bExist)
            {
                TiXmlElement *pLaneLinkSuc = new TiXmlElement(XML_SUCCESSOR);
                pLaneLink->LinkEndChild(pLaneLinkSuc);

                pLaneLinkSuc->SetAttribute(XML_ID, itLane->link.successor.id.c_str());
            }
        }

        if(itLane->width.bExist)
        {
            TiXmlElement *pLaneWidth = new TiXmlElement(XML_WIDTH);
            pLaneSectionLayout->LinkEndChild(pLaneWidth);

            pLaneWidth->SetDoubleAttribute(XML_A, itLane->width.coefficients.a);
            pLaneWidth->SetDoubleAttribute(XML_B, itLane->width.coefficients.b);
            pLaneWidth->SetDoubleAttribute(XML_C, itLane->width.coefficients.c);
            pLaneWidth->SetDoubleAttribute(XML_D, itLane->width.coefficients.d);
            pLaneWidth->SetAttribute(XML_SOFFSET, itLane->width.sOffset.c_str());
        }

        if(itLane->roadMark.bExist)//roadMark节点少东西???
        {
            TiXmlElement *pLaneRoadMark = new TiXmlElement(XML_ROADMARK);
            pLaneSectionLayout->LinkEndChild(pLaneRoadMark);

            pLaneRoadMark->SetAttribute(XML_COLOR, itLane->roadMark.color.c_str());
            pLaneRoadMark->SetAttribute(XML_SOFFSET, itLane->roadMark.sOffset.c_str());
            pLaneRoadMark->SetAttribute(XML_TYPE, itLane->roadMark.type.c_str());
            pLaneRoadMark->SetAttribute(XML_WEIGHT, itLane->roadMark.weight.c_str());
        }

        if(itLane->speed.bExist)
        {
            TiXmlElement *pLaneSpeed = new TiXmlElement(XML_SPEED);
            pLaneSectionLayout->LinkEndChild(pLaneSpeed);

            pLaneSpeed->SetAttribute(XML_SOFFSET, itLane->speed.sOffset.c_str());
            pLaneSpeed->SetAttribute(XML_MAX, itLane->speed.max.c_str());
        }

        if(itLane->height.bExist)
        {
            TiXmlElement *pLaneHeight = new TiXmlElement(XML_HEIGHT);
            pLaneSectionLayout->LinkEndChild(pLaneHeight);

            pLaneHeight->SetAttribute(XML_SOFFSET, itLane->height.sOffset.c_str());
            pLaneHeight->SetAttribute(XML_INNER, itLane->height.inner.c_str());
            pLaneHeight->SetAttribute(XML_OUTER, itLane->height.outer.c_str());
        }

        if(itLane->userData.bExist)
        {
            TiXmlElement *pLaneUserData = new TiXmlElement(XML_USERDATA);
            pLaneSectionLayout->LinkEndChild(pLaneUserData);

            pLaneUserData->SetAttribute(XML_CODE, itLane->userData.code.c_str());

            if(itLane->userData.style.bExist)
            {
                TiXmlElement *pUserDataStyle = new TiXmlElement(XML_STYLE);
                pLaneUserData->LinkEndChild(pUserDataStyle);

                pLaneUserData->SetAttribute(XML_SOFFSET, itLane->userData.style.sOffset.c_str());
                pLaneUserData->SetAttribute(XML_LANESTYLE, itLane->userData.style.laneStyle.c_str());
                pLaneUserData->SetAttribute(XML_MAPPING, itLane->userData.style.mapping.c_str());
            }

            if(itLane->userData.fillet.bExist)
            {
                TiXmlElement *pUserDataFillet = new TiXmlElement(XML_FILLET);
                pLaneUserData->LinkEndChild(pUserDataFillet);

                pUserDataFillet->SetAttribute(XML_POS, itLane->userData.fillet.pos.c_str());
                pUserDataFillet->SetAttribute(XML_STYLE, itLane->userData.fillet.style.c_str());
                pUserDataFillet->SetAttribute(XML_ID, itLane->userData.fillet.id.c_str());
            }
        }
    }
}

void MapInfoWrite::addRoadObjects(TiXmlElement *pRoad, const Objects objects)
{
    delRoadObjects(pRoad);//保证一个road节点下只有一个objects节点

    TiXmlElement *pRoadObjects = new TiXmlElement(XML_OBJECTS);
    pRoad->LinkEndChild(pRoadObjects);

    for(auto itObject = objects.qvecObject.begin(); itObject != objects.qvecObject.end(); itObject++)
    {
        TiXmlElement *pRoadObjectsObject = new TiXmlElement(XML_OBJECT);
        pRoadObjects->LinkEndChild(pRoadObjectsObject);

        pRoadObjectsObject->SetAttribute(XML_ID, itObject->id.c_str());
        pRoadObjectsObject->SetAttribute(XML_TYPE, itObject->type.c_str());
        pRoadObjectsObject->SetAttribute(XML_NAME, itObject->name.c_str());
        pRoadObjectsObject->SetDoubleAttribute(XML_S, itObject->s);
        pRoadObjectsObject->SetDoubleAttribute(XML_T, itObject->t);
        pRoadObjectsObject->SetDoubleAttribute(XML_ZOFFSET, itObject->zOffset);
        pRoadObjectsObject->SetDoubleAttribute(XML_LENGTH, itObject->length);
        pRoadObjectsObject->SetDoubleAttribute(XML_WIDTH, itObject->width);
        pRoadObjectsObject->SetDoubleAttribute(XML_HEIGHT, itObject->height);
        pRoadObjectsObject->SetDoubleAttribute(XML_HDG, itObject->hdg);
        pRoadObjectsObject->SetDoubleAttribute(XML_PITCH, itObject->pitch);
        pRoadObjectsObject->SetDoubleAttribute(XML_ROLL, itObject->roll);

        if(itObject->repeat.bExist)//看了长沙地图，object节点下还有可能有coordinates节点???
        {
            TiXmlElement *pRepeat = new TiXmlElement(XML_REPEAT);
            pRoadObjectsObject->LinkEndChild(pRepeat);

            pRepeat->SetDoubleAttribute(XML_S, itObject->repeat.s);
            pRepeat->SetDoubleAttribute(XML_LENGTH, itObject->repeat.length);
            pRepeat->SetDoubleAttribute(XML_DISTANCE, itObject->repeat.distance);
            pRepeat->SetDoubleAttribute(XML_TSTART, itObject->repeat.tStart);
            pRepeat->SetDoubleAttribute(XML_TEND, itObject->repeat.tEnd);
            pRepeat->SetDoubleAttribute(XML_WIDTHSTART, itObject->repeat.widthStart);
            pRepeat->SetDoubleAttribute(XML_WIDTHEND, itObject->repeat.widthEnd);
            pRepeat->SetDoubleAttribute(XML_HEIGHTSTART, itObject->repeat.heightStart);
            pRepeat->SetDoubleAttribute(XML_HEIGHTEND, itObject->repeat.heightEnd);
            pRepeat->SetDoubleAttribute(XML_ZOFFSETSTART, itObject->repeat.zOffsetStart);
            pRepeat->SetDoubleAttribute(XML_ZOFFSETEND, itObject->repeat.zOffsetEnd);
        }
    }
}

void MapInfoWrite::delRoadObjects(TiXmlElement *pRoad)
{
    TiXmlNode *pRoadObjects = pRoad->FirstChild(XML_OBJECTS);
    if(nullptr != pRoadObjects)
    {
        pRoad->RemoveChild(pRoadObjects);
    }
}

void MapInfoWrite::addRoadSignals(TiXmlElement *pRoad, const Signals roadSignals)
{
    delRoadSignals(pRoad);//保证一个road节点下只有一个signals节点

    TiXmlElement *pRoadSignals = new TiXmlElement(XML_SIGNALS);
    pRoad->LinkEndChild(pRoadSignals);

    for(auto itSignal = roadSignals.qvecSignal.begin(); itSignal != roadSignals.qvecSignal.end(); itSignal++)
    {
        TiXmlElement *pRoadSignalsSignal = new TiXmlElement(XML_SIGNAL);
        pRoadSignals->LinkEndChild(pRoadSignalsSignal);

        pRoadSignalsSignal->SetDoubleAttribute(XML_S, itSignal->s);
        pRoadSignalsSignal->SetDoubleAttribute(XML_T, itSignal->t);
        pRoadSignalsSignal->SetAttribute(XML_ID, itSignal->id.c_str());
        pRoadSignalsSignal->SetAttribute(XML_NAME, itSignal->name.c_str());
        pRoadSignalsSignal->SetAttribute(XML_DYNAMIC, itSignal->dynamic.c_str());
        pRoadSignalsSignal->SetAttribute(XML_ORIENTATION, itSignal->orientation.c_str());
        pRoadSignalsSignal->SetDoubleAttribute(XML_ZOFFSET, itSignal->zOffset);
        pRoadSignalsSignal->SetAttribute(XML_TYPE, itSignal->type.c_str());
        pRoadSignalsSignal->SetAttribute(XML_COUNTRY, itSignal->country.c_str());
        pRoadSignalsSignal->SetAttribute(XML_SUBTYPE, itSignal->subtype.c_str());

        if(itSignal->userData.bExist)
        {
            TiXmlElement *pSignalUserData = new TiXmlElement(XML_USERDATA);
            pRoadSignalsSignal->LinkEndChild(pSignalUserData);

            pSignalUserData->SetAttribute(XML_CODE, itSignal->userData.code.c_str());
            pSignalUserData->SetDoubleAttribute(XML_VALUE, itSignal->userData.value);
        }
    }
}

void MapInfoWrite::delRoadSignals(TiXmlElement *pRoad)
{
    TiXmlNode *pRoadSignals = pRoad->FirstChild(XML_SIGNALS);
    if(nullptr != pRoadSignals)
    {
        pRoad->RemoveChild(pRoadSignals);
    }
}

//先清空所有controller节点，然后把MapInfo中的controller信息重新添加进去
void MapInfoWrite::resetController()
{
    delController();

    const QVector<SController> qvecController = __MAPDATA->getController();
    for(auto itController = qvecController.begin(); itController != qvecController.end(); itController++)
    {
        addController(*itController);
    }
}

//添加一个controller节点
void MapInfoWrite::addController(const SController &controller)
{
    TiXmlElement *pRoot = GlobalRwXml::getRwxml()->getDoc()->RootElement();

    TiXmlElement *pController = getControllerElement(controller);
    pRoot->LinkEndChild(pController);
}

//删除全部controller节点
void MapInfoWrite::delController()
{
    auto opxml = GlobalRwXml::getRwxml();
    TiXmlNode *pControllerNode = opxml->getDoc()->RootElement()->FirstChild(XML_CONTROLLER);
    TiXmlNode *pControllerNodeNext = pControllerNode->NextSibling();
    while (nullptr != pControllerNode)
    {
        opxml->delSingleNode(pControllerNode);
        pControllerNode = pControllerNodeNext;
        pControllerNodeNext = pControllerNode->NextSibling();
    }
}

void MapInfoWrite::delController(const SController &controller)
{
    delController(controller.id);
}

void MapInfoWrite::delController(const std::string &controllerId)
{
    auto opxml = GlobalRwXml::getRwxml();
    TiXmlNode *pControllerNode = opxml->selectSingleNode(XML_CONTROLLER, XML_ID, controllerId);
    opxml->delSingleNode(pControllerNode);
}

void MapInfoWrite::updateController(const SController &controller)
{
    auto opxml = GlobalRwXml::getRwxml();
    TiXmlNode *pControllerNode = opxml->selectSingleNode(XML_CONTROLLER, XML_ID, controller.id);
    opxml->getDoc()->RootElement()->InsertAfterChild(pControllerNode, *getControllerElement(controller));
    opxml->delSingleNode(pControllerNode);
}

//先清空所有junction节点，然后把MapInfo中的junction信息重新添加进去
void MapInfoWrite::resetJunction()
{
    delJunction();

    const QVector<Junction> qvecJunction = __MAPDATA->getJunction();
    for(auto itJunction = qvecJunction.begin(); itJunction != qvecJunction.end(); itJunction++)
    {
        addJunction(*itJunction);
    }
}

//添加一个junction节点
void MapInfoWrite::addJunction(const Junction &junction)
{
    TiXmlElement *pRoot = GlobalRwXml::getRwxml()->getDoc()->RootElement();

    TiXmlElement *pJunction = getJunctionElement(junction);
    pRoot->LinkEndChild(pJunction);
}

//删除所有junction节点
void MapInfoWrite::delJunction()
{
    auto opxml = GlobalRwXml::getRwxml();
    TiXmlNode *pJunctionNode = opxml->getDoc()->RootElement()->FirstChild(XML_JUNCTION);
    TiXmlNode *pJunctionNodeNext = pJunctionNode->NextSibling();
    while (nullptr != pJunctionNode)
    {
        opxml->delSingleNode(pJunctionNode);
        pJunctionNode = pJunctionNodeNext;
        pJunctionNodeNext = pJunctionNode->NextSibling();
    }
}

void MapInfoWrite::delJunction(const Junction &junction)
{
    delJunction(junction.id);
}

void MapInfoWrite::delJunction(const std::string &junctionId)
{
    auto opxml = GlobalRwXml::getRwxml();
    TiXmlNode *pJunctionNode = opxml->selectSingleNode(XML_JUNCTION, XML_ID, junctionId);
    opxml->delSingleNode(pJunctionNode);
}

void MapInfoWrite::updateJunction(const Junction &junction)
{
    auto opxml = GlobalRwXml::getRwxml();
    TiXmlNode *pJunctionNode = opxml->selectSingleNode(XML_JUNCTION, XML_ID, junction.id);
    opxml->getDoc()->RootElement()->InsertAfterChild(pJunctionNode, *getJunctionElement(junction));
    opxml->delSingleNode(pJunctionNode);
}

TiXmlElement *MapInfoWrite::getRoadElement(const SRoad &road)
{
    TiXmlElement *pRoad = new TiXmlElement(XML_ROAD);

    //设置road属性
    pRoad->SetAttribute(XML_ID, road.id.c_str());
    pRoad->SetAttribute(XML_NAME, road.name.c_str());
    pRoad->SetAttribute(XML_JUNCTION, road.junction.c_str());
    pRoad->SetDoubleAttribute(XML_LENGTH, road.length);

    addRoadLink(pRoad, road.roadLink);
    addRoadType(pRoad, road.roadType);
    addPlanView(pRoad, road.planView);
    addElevationProfile(pRoad, road.elevationProfile);
    addRoadLanes(pRoad, road.lanes);
    addRoadObjects(pRoad, road.objects);
    addRoadSignals(pRoad, road.roadSignals);

    return pRoad;
}

TiXmlElement *MapInfoWrite::getControllerElement(const SController &controller)
{
    TiXmlElement *pController = new TiXmlElement(XML_CONTROLLER);

    //设置controller属性
    pController->SetAttribute(XML_ID, controller.id.c_str());

    for(auto itControl = controller.qvecControl.begin(); itControl != controller.qvecControl.end(); itControl++)
    {
        TiXmlElement *pControl = new TiXmlElement(XML_CONTROL);
        pController->LinkEndChild(pControl);

        pControl->SetAttribute(XML_SIGNALID, itControl->signalId.c_str());
        pControl->SetAttribute(XML_TYPE, itControl->type.c_str());
    }

    return pController;
}

TiXmlElement *MapInfoWrite::getJunctionElement(const Junction &junction)
{
    TiXmlElement *pJunction = new TiXmlElement(XML_JUNCTION);

    //设置controller属性
    pJunction->SetAttribute(XML_ID, junction.id.c_str());
    pJunction->SetAttribute(XML_NAME, junction.name.c_str());

    for(auto itConnection = junction.qvecConnection.begin(); itConnection != junction.qvecConnection.end(); itConnection++)
    {
        TiXmlElement *pConnection = new TiXmlElement(XML_CONNECTION);
        pJunction->LinkEndChild(pConnection);

        pConnection->SetAttribute(XML_ID, itConnection->id.c_str());
        pConnection->SetAttribute(XML_INCOMINGROAD, itConnection->incomingRoad.c_str());
        pConnection->SetAttribute(XML_CONNECTINGROAD, itConnection->connectingRoad.c_str());
        pConnection->SetAttribute(XML_CONTACTPOINT, itConnection->contactPoint.c_str());

        for(auto itLaneLink = itConnection->qvecLaneLink.begin(); itLaneLink != itConnection->qvecLaneLink.end(); itLaneLink++)
        {
            TiXmlElement *pLaneLink = new TiXmlElement(XML_LANELINK);
            pConnection->LinkEndChild(pLaneLink);

            pLaneLink->SetAttribute(XML_FROM, itLaneLink->from.c_str());
            pLaneLink->SetAttribute(XML_TO, itLaneLink->to.c_str());
        }
    }

    for(auto itController = junction.qvecController.begin(); itController != junction.qvecController.end(); itController++)
    {
        TiXmlElement *pController = new TiXmlElement(XML_CONNECTION);
        pJunction->LinkEndChild(pController);

        pController->SetAttribute(XML_ID, itController->id.c_str());
    }

    return pJunction;
}
